#include <Utils/Type.h>
#include "HalAlgAES.h"
#include "HalAlgGloBuff.h"
#include "../alg_pr/ALGAes_PR.h"
#include <string.h>

#define AES_BLOCK_SIZE 	16
#define AES_KEY_LEN 	32
#define AES_IV_LEN		16


UINT32 HalAlgAES_Init(UINT8 Key[], UINT8 KLen, UINT8 IV[])
{
	UINT8 *l_ptr;
	
	if(Key != NULL)
	{
		l_ptr = (UINT8*)GetAlgKeyBuff();
		memcpy(l_ptr, Key, KLen);      
	}
	
	if(IV != NULL)
	{
		l_ptr = (UINT8*)GetAlgIVBuff();
		memcpy(l_ptr, IV, AES_IV_LEN);
	}
	 
   	return RT_OK;
}

UINT32 HalAlgAES_Encrypt_Update(UINT32 Mode, UINT8 *pInBuf, UINT16 nSize, UINT8 *pOutBuf)
{
    UINT8 nRet;
    UINT8 l_mode;
    UINT8 *l_iv_ptr, *l_key_ptr;

	if(pInBuf ==NULL)
	{
		return RT_FAIL;
	}
	
	if(nSize % AES_BLOCK_SIZE != 0)
	{
		return RT_FAIL;	
	}
	
	l_iv_ptr = (UINT8*)GetAlgIVBuff();
	l_key_ptr = (UINT8*)GetAlgKeyBuff();
	
	switch(Mode)
	{
		case HALALGAES_MODE_ECB_128:
			l_mode = AES128_ECB;
			l_iv_ptr = NULL;
			break;
		case HALALGAES_MODE_CBC_128:
			l_mode = AES128_CBC;			
			break;
		case HALALGAES_MODE_ECB_192:
		    l_mode = AES192_ECB;
		    l_iv_ptr = NULL;
			break;
		case HALALGAES_MODE_CBC_192:
			l_mode = AES192_CBC;
			break;
		case HALALGAES_MODE_ECB_256:
            l_mode = AES256_ECB;
            l_iv_ptr = NULL;
			break;
		case HALALGAES_MODE_CBC_256:
			l_mode = AES256_CBC;
			break;
		default :
			return RT_FAIL;
	}
	
    nRet = ALGAes_PR_Run(AES_ENCRYPT, l_mode, pInBuf, pOutBuf, nSize, l_key_ptr, l_iv_ptr);
   
	return nRet;

}
UINT32 HalAlgAES_Decrypt_Update(UINT32 Mode, UINT8 *pInBuf, UINT16 nSize, UINT8* pOutBuf)
{
    UINT8 nRet;
    UINT8 l_mode;
    UINT8 *l_iv_ptr, *l_key_ptr;

	if(pInBuf ==NULL)
	{
		return RT_FAIL;
	}
	
	if(nSize%AES_BLOCK_SIZE != 0)
	{
		return RT_FAIL;	
	}
	
	l_iv_ptr =(UINT8*) GetAlgIVBuff();
	l_key_ptr = (UINT8*)GetAlgKeyBuff();
	
	switch(Mode)
	{
		case HALALGAES_MODE_ECB_128:
			l_mode = AES128_ECB;
			l_iv_ptr = NULL;
			break;
		case HALALGAES_MODE_CBC_128:
			l_mode = AES128_CBC;			
			break;
		case HALALGAES_MODE_ECB_192:
		    l_mode = AES192_ECB;
		    l_iv_ptr = NULL;
			break;
		case HALALGAES_MODE_CBC_192:
			l_mode = AES192_CBC;
			break;
		case HALALGAES_MODE_ECB_256:
            l_mode = AES256_ECB;
            l_iv_ptr = NULL;
			break;
		case HALALGAES_MODE_CBC_256:
			l_mode = AES256_CBC;
			break;
		default :
			return RT_FAIL;
	} 
	
    nRet = ALGAes_PR_Run(AES_DECRYPT, l_mode, pInBuf, pOutBuf, nSize, l_key_ptr, l_iv_ptr);
   
	return nRet;
}

UINT32 HalAlgAES_Final(void)
{
	UINT8 *l_ptr;
	
	l_ptr = (UINT8*)GetAlgIVBuff();
	memset(l_ptr, 0, AES_IV_LEN);
	l_ptr = (UINT8*)GetAlgKeyBuff();
	memset(l_ptr, 0, AES_KEY_LEN);
	
	return RT_OK;
}

